#include "msghttp.h"
int ininit_socket(unsigned int port)
{
    int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockfd < 0)
    {
        perror("creating socket failed");
        return -1;
    }
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(port);
    serveraddr.sin_addr.s_addr = INADDR_ANY;
    if (bind(sockfd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
    {
        perror("binding failed");
        exit(-1);
    }
    if (listen(sockfd, 128) < 0)
    {
        perror("listening failed");
        exit(-1);
    }
    return sockfd;
}
void get_handler(int sockfd, const struct get_header *header)
{
    switch (header->state)
    {
    case GET_MOREN:
        get_moren_handler(sockfd, header);
        break;
    case GET_WUCAN:
        get_moren_handler(sockfd, header);
        break;
    case GET_YOUCAN:
        get_moren_handler(sockfd, header);
        break;
    }
}
void *message_handler(char *str, int *flag)
{
    // struct get_header *header ;
    if (strncmp(str, "GET", 3) == 0 || strncmp(str, "GET", 3) == 0)
    {
        struct get_header *header = (struct get_header *)malloc(sizeof(struct get_header));
        if (header == NULL)
        {
            return NULL;
        }
        *flag = GET;
        header->method = GET;
        int i = 0, j = 0, k = 0, c = 0;
        if (strstr(str, "html"))
        {
            char *tstart = strchr(str, '/');
            tstart++;
            char *tend = strchr(tstart, '?');
            if (tend == NULL) // 无参
            {
                header->state = GET_WUCAN;
                tend = strchr(tstart, ' ');
                header->patter[0] = -1;
                strncpy(header->page, tstart, tend - tstart);
            }
            else // 有参数
            {
                header->state = GET_YOUCAN;
                strncpy(header->page, tstart, tend - tstart);
                tstart = strchr(str, '?');
                tstart++;
                tend = strchr(tstart, ' ');
                strncpy(header->patter, tstart, tend - tstart);
            }
        }
        else
        {
            header->state = GET_MOREN;
            header->patter[0] = -1;
            strcpy(header->page, "index.html");
        }

        return header;
    }
    else if (strncmp(str, "POST", 4) == 0 || strncmp(str, "POST", 4) == 0)
    {
        puts("post");
        struct post_header *header = (struct post_header *)malloc(sizeof(struct post_header));
        if (header == NULL)
        {
            return NULL;
        }
        *flag = POST;
        header->method = POST;
        int i = 0, j = 0, k = 0, c = 0;
        if (strstr(str, "html"))
        {
            char *tstart = strchr(str, '/');
            tstart++;
            char *tend = strchr(tstart, ' ');
            strncpy(header->page, tstart, tend - tstart);
        }
        return header;
    }
}
int get_moren_handler(int sockfd, const struct get_header *header)
{
    const char *respone_header = "HTTP/1.1 200 OK\r\n\r\n";
    char path[64] = {0};
    sprintf(path, "wwwroot//%s", header->page);
    int fd = open(path, O_RDONLY);
    if (fd == -1)
    {
        sprintf(path, "wwwroot//%s", "404.html");
        fd = open(path, O_RDONLY);
    }
    write(sockfd, respone_header, strlen(respone_header));
    char buf[1024] = {0};
    int nbytes = 0;
    while ((nbytes = read(fd, buf, 1024)) != 0)
    {
        write(sockfd, buf, nbytes);
    }

    // DIR *dir = opendir("wwwroot");
    // struct dirent *tdir = NULL;
    // if (dir == NULL)
    // {
    //     perror("opening dir error");
    //     return -1;
    // }
    // while ((tdir = readdir(dir)) != NULL)
    // {
    //     // 判断是否为隐藏文件
    //     if (strncpy(tdir->d_name, "index.html", 10))
    //     {
    //         int fd = open("wwwroot/index.html");
    //         write(sockfd, respone_header, strlen(respone_header));
    //         sendfile(sockfd, fd, NULL, tdir->d_off)
    //     }
    // }
}
int get_wucan_handler(int sockfd, const struct get_header *header)
{
    const char *respone_header = "HTTP/1.1 200 OK\r\n\r\n";
    char path[64] = {0};
    sprintf(path, "wwwroot//%s", header->page);
    int fd = open(path, O_RDONLY);
    if (fd == -1)
    {
        sprintf(path, "wwwroot//%s", "404.html");
        fd = open(path, O_RDONLY);
    }
    write(sockfd, respone_header, strlen(respone_header));
    char buf[1024] = {0};
    int nbytes = 0;
    while ((nbytes = read(fd, buf, 1024)) != 0)
    {
        write(sockfd, buf, nbytes);
    }
}
void canshu_handler(const struct get_header *header)
{
    puts("参数");
    puts(header->patter);
}
int init_post_par(struct post_header *header, char *pr)
{
    // puts(pr);
    if (strstr(pr, "username") != NULL)
        header->state = POST_CANSHU_UP;
    else if (strstr(pr, "data") != NULL)
        header->state = POST_CANSHU_DATA;
    strcpy(header->patter, pr);
}
void post_handler(int sockfd, struct post_header *header)
{
    puts("post handler");
    switch (header->state)
    {
    case POST_CANSHU_DATA:
        puts("data");
        puts(header->patter);
        post_data_handler(sockfd, header);
        break;
    case POST_CANSHU_UP:
        break;
    }
}
void * fun(void *arg)
{

}
int post_data_handler(int sockfd, struct post_header *header)
{
    pthread_t thread1;
    pthread_create(&thread1, 0, fun, NULL);
    puts("post_data_handler");
    key_t key1 = ftok(".", 'a');
    if (key1 < 0)
    {
        perror("ftokm err");
        return -1;
    }
    int msgid = msgget(key1, IPC_CREAT | IPC_EXCL | 0666);
    if (msgid <= 0)
    {
        if (errno == EEXIST)
            msgid = msgget(key1, 0666);
        else
        {
            perror("msgget err");
            return -1;
        }
    }
    key_t key;
    /*不同进程可以用相同的key值,来访问同一块共享内存 */

    // 创建key值 ftok
    // 第一个参数:以存在的路径名
    key = ftok("./1in_out.c", 'b');
    if (key < 0)
    {
        perror("ftok err");
        return -1;
    }
    int shmid = shmget(key, 128, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid < 0)
    {
        if (errno == EEXIST)
            shmid = shmget(key, 128, 0666);
        else
        {
            perror("shmget err");
            return -1;
        }
    }
    unsigned short *p = (unsigned short *)shmat(shmid, NULL, 0);
    if (p == (char *)-1)
    {
        perror("shmat err");
        return -1;
    }
    printf("get:%d  %d  %d  %d\n",p[0],p[1],p[2],p[3]);
    struct msg msg_s;

    // const char *respone_header = "HTTP/1.1 200 OK\r\n\r\n";
    int nbytes = 0;
    char *tstart = strchr(header->patter, '=');
    tstart++;
    char *tend = strchr(tstart, 'd');
    char 
    data1[32] = {0};
    char data2[32] = {0};
    sprintf(data1, tstart, tend - tstart);
    tstart = strchr(tend, '=');
    tstart++;
    tend = strchr(tstart, '\"');
    sprintf(data2, tstart, tend - tstart);
    int result = atoi(data1) + atoi(data2);
    msg_s.pos1 = LED;
    msg_s.pos1 = BEEP;
    msg_s.cmd1 = atoi(data1);
    msg_s.cmd2 = atoi(data2);
    printf("test:%d %d\n",msg_s.cmd1,msg_s.cmd2);
    msgsnd(msgid, &msg_s,
           sizeof(msg_s), 0);
   // msgctl(msgid, IPC_RMID, NULL);


    printf("%d\n", result);
    char response[256] = {0};
    sprintf(response, "%s%d%d%d%d", "HTTP/1.1 200 OK\r\n\r\n", p[0],p[1],p[2],p[3]);
    puts(response);
    nbytes = write(sockfd, response, strlen(response));
    if (nbytes < 0)
    {
        perror("sending failed");
        return -1;
    }
    puts("end here");
    return 0;
}
int post_up_handler(int sockfd, struct post_header *header)
{
    const char *respone_header = "HTTP/1.1 200 OK\r\n\r\n";
    char path[64] = {0};
    sprintf(path, "wwwroot//%s", header->page);
    int fd = open(path, O_RDONLY);
    if (fd == -1)
    {
        sprintf(path, "wwwroot//%s", "404.html");
        fd = open(path, O_RDONLY);
    }
    write(sockfd, respone_header, strlen(respone_header));
    char buf[1024] = {0};
    int nbytes = 0;
    while ((nbytes = read(fd, buf, 1024)) != 0)
    {
        write(sockfd, buf, nbytes);
    }
}